﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Management;
using System.Diagnostics;
using System.Threading;
using System.Reflection;
using DigitalSolutionLibrary.Utilities;
using DigitalSolutionLibrary.Security;

namespace DigitalSolutionManagement
{
    public partial class frmAppError : BaseFormEdit
    {
        private Thread th;

        private string GetSystemInformation()
        {
            string cpuInfo = String.Empty;
            string operationInfo = String.Empty;
            string serverPack = String.Empty;
            UInt64 totalPhysicalMemory = 0;
            UInt32 maxClockSpeed = 0;

            try
            {
                ArrayList sysInfo;
                sysInfo = GetStuff("Win32_Processor");
                foreach (PropertyData sp in sysInfo)
                {
                    if (sp.Name == "Name")
                    {
                        cpuInfo = sp.Value.ToString();
                    }

                    if (sp.Name == "MaxClockSpeed")
                    {
                        maxClockSpeed = (UInt32)sp.Value;
                    }

                    if (cpuInfo != String.Empty && maxClockSpeed != 0)
                        break;
                }

                sysInfo = new ArrayList();
                sysInfo = GetStuff("Win32_OperatingSystem");
                foreach (PropertyData sp in sysInfo)
                {
                    if (sp.Name == "Caption")
                    {
                        operationInfo = sp.Value.ToString();
                    }
                    else if (sp.Name == "CSDVersion")
                    {
                        serverPack = sp.Value.ToString();
                    }
                    else if (sp.Name == "TotalVisibleMemorySize")
                    {
                        totalPhysicalMemory = (UInt64)sp.Value;
                    }

                    if (operationInfo != String.Empty && serverPack != String.Empty && totalPhysicalMemory != 0)
                        break;
                }

                return "- CPU: " + cpuInfo + " (" + maxClockSpeed + "Hz)\r\n- RAM: " + totalPhysicalMemory + " Bytes\r\n- OS name: " + operationInfo + "\r\n- Service pack: " + serverPack + "\r\n";
            }
            catch
            {
                return "Error getting system information\r\n";
            }
        }

        public ArrayList GetStuff(string queryObject)
        {
            ManagementObjectSearcher searcher;
            ArrayList hd = new ArrayList();
            try
            {
                searcher = new ManagementObjectSearcher("SELECT * FROM " + queryObject);
                foreach (ManagementObject wmi_HD in searcher.Get())
                {
                    PropertyDataCollection searcherProperties = wmi_HD.Properties;
                    foreach (PropertyData sp in searcherProperties)
                    {
                        hd.Add(sp);
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            return hd;
        }

        private string ProcessError(Exception e)
        {
            StackTrace st = new StackTrace(e, true);
            StackFrame[] frames = st.GetFrames();
            string headerMessage = "- App name: " + Assembly.GetExecutingAssembly().GetName().Name;
            headerMessage += "\r\n- App version: " + Assembly.GetExecutingAssembly().GetName().Version.ToString();
            headerMessage += "\r\n- Employee ID: " + Program.EmpId;
            headerMessage += "\r\n- Date: " + DateTime.Now.ToString();

            string errorMessage = String.Empty;
            bool tracesuccess = false;
            foreach (StackFrame frame in frames)
            {
                try
                {
                    errorMessage += "\r\n- Message: " + e.Message;
                    string path = frame.GetFileName();
                    int i = path.LastIndexOf('\\');
                    if (i > 0)
                    {
                        errorMessage += "\r\n- Path: " + path.Substring(i + 1, path.Length - i - 1);
                    }
                    errorMessage += "\r\n- Method: " + frame.GetMethod().Name;
                    errorMessage += "\r\n- Line: "+ frame.GetFileLineNumber();
                    tracesuccess = true;
                    break;
                }
                catch
                {
                }
            }

            if (!tracesuccess)
            {
                errorMessage = String.Empty;
                errorMessage += "\r\n************************STACK-TRACE************************\r\n";
                errorMessage += e.StackTrace;
                errorMessage += "- Message: " + e.Message + Environment.NewLine;
                errorMessage += "- StackTrace : " + e.StackTrace + Environment.NewLine;
                if (e.InnerException != null)
                {
                    errorMessage += "- Inner1 : " + e.InnerException.Message + Environment.NewLine;
                    if (e.InnerException.InnerException != null)
                    {
                        errorMessage += "- Inner2 : " + e.InnerException.InnerException.Message + Environment.NewLine;
                    }
                }
            }

            return headerMessage + errorMessage;
        }

        private void ProcessSystemInfoAndError(Exception e)
        {
            txtMessage.Text = GetSystemInformation();
            txtMessage.AppendText(ProcessError(e));
            processing1.HideProcessing();
        }

        private void SendError()
        {
            SendMail mail = new SendMail("huynhthanhdu@gmail.com", TripleDES.Decryption("wm4XiVWJmoiwFaRhXSYBQw=="), "huynhthanhdu@gmail.com", "DSCo", "huynhthanhdu@gmail.com", "DSCo Application Error", txtMessage.Text.Replace("\r\n","<br />"));
            if (mail.Send())
            {
                processing1.HideProcessing();
                MessageBox.Show("Gởi thông báo lỗi thành công", "DSCo", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                processing1.HideProcessing();
                MessageBox.Show("Không thể gởi thông báo lỗi, vui lòng thử lại sau", "DSCo", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public frmAppError(Exception e)
        {
            CheckForIllegalCrossThreadCalls = false;
            InitializeComponent();
            
            processing1.ShowProcessing();
            th = new Thread(()=>ProcessSystemInfoAndError(e));
            th.Start();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {            
            Environment.Exit(0);
        }

        private void btnRestartApp_Click(object sender, EventArgs e)
        {
            Application.Restart();
            Environment.Exit(0);
        }

        private void btnSendErr_Click(object sender, EventArgs e)
        {
            processing1.ShowProcessing();
            th = new Thread(() => SendError());
            th.Start();
        }
    }
}
